{
  importer , import from xml

  @Author    csyap
  @Version   2010.11.11 first version
}
unit kgs_importer;

interface
uses classes,sysutils,kgs_classes,ecxmlparser;

type
   TKGSimporter = class(tpersistent)
     protected
       fdb:TKGSDatabase;
       procedure addxmlnode(childstr:widestring; node:TXMLContainerNode);
     public
     xmlnodecount:integer;
     currentnode:integer;
     onAddXmlNode:TNotifyEvent;
     constructor create(db:TKGSDatabase);
     destructor destroy;override;
     procedure addxml(xmlfn:widestring);

   end;



implementation

{ TKGSimporter }

constructor TKGSimporter.create(db: TKGSDatabase);
begin
  fdb:=db;
end;

destructor TKGSimporter.destroy;
begin

  inherited;
end;

procedure TKGSimporter.addxmlnode(childstr:widestring; node:TXMLContainerNode);
var
  subnode:TXMLItem;
  subcontainer:TXMLContainerNode;
  childs:TStringList;
  cssl,childsid :TStringList;
  id,cs,s:string;
  i,j,level:integer;
  body:tstringlist;
  function getid(level:integer=-1):string;
  var
    i:integer;
  begin
    if level=-1 then begin
      childsid.Delimiter:='.';
      result:=childsid.DelimitedText;
      childsid.Delimiter:=',';
    end else begin
      result:='';
      for i:=0 to level do begin
        result:=result+childsid[i];
        if i<level then result:=result+'.';
      end;

    end;
  end;
  procedure addmeta(metanode:TXMLContainerNode);
  var
    id,metaname,metavalue,metaextra:string;
  begin
    id:=metanode.GetAttributes('id','');
    metaname:=metanode.GetAttributes('name','');
    metavalue:=metanode.GetAttributes('value','');
    metaextra:=metanode.GetAttributes('extra','');
    if (id<>'') and (metaname<>'') then
    fdb.putmeta(id,metaname,metavalue,metaextra);
  end;
  procedure addbody;
  var
    id:string;
  begin
     id:=trim(getid);
     if (body.count>0) and (id<>'') then begin
       fdb.putrow(getid,body.Text);
       body.clear;
     end;
  end;
begin
  body:=tstringlist.create;
  childs:=Tstringlist.create;
  childsid:=Tstringlist.create;
  childs.add( Utf8Encode(childstr));
  childsid.add('');//unknown yet
  xmlnodecount:=node.subitemcount;

  for i:=0 to node.subitemcount-1 do begin
    currentnode:=i;

    if assigned(onAddXmlNode) then onAddXmlNode(self);

    subnode:=node.SubItems[i];
    if (subnode is TXMLContainerNode)then begin
       subcontainer:=TXMLContainerNode(subnode);
       level:=childs.indexof(subcontainer.Name);
       if subcontainer.name='META' then begin
         addmeta(subcontainer);
         continue;
       end;
       if level=-1 then continue;

       addbody;

       if subcontainer.hasattribute('id') then begin
         childsid[level]:=subcontainer.GetAttributes('id','');
       end;

       if childs.count-1>level then
       for j:=childs.count-1 downto level do begin
         childs.Delete(j);
         childsid.delete(j);
       end;

       if subcontainer.hasattribute('child') then begin
        cs:=subcontainer.GetAttributes('child','');
        if cs<>'' then begin
          cssl:=tstringlist.create;cssl.text:=cs;
          childs.AddStrings(cssl);
          childsid.addstrings(cssl);
          cssl.free;
        end;
       end;
    end else begin
      if subnode.ItemType=itText then begin
        s:=subnode.AsString;
        if s<>#$ef#$bb#$bf then body.add(subnode.AsString);
      end;
    end;
  end;

  addbody;

  childs.free;
  childsid.free;
  body.Free;
end;


procedure TKGSimporter.addxml(xmlfn: widestring);
var
  xmlparser:TXMLparser;
  fn:string;
  breaker:Tstringlist;
  i:integer;
begin
  fn:=utf8decode(xmlfn);
  if not fileexists(fn) then exit;



  xmlparser:=TXmlParser.Create(nil);

  fdb.begintransaction;
  xmlparser.LoadFromFile(fn);
  fdb.commit;

  addxmlnode('BOOK',xmlparser.root);

  xmlparser.free;
end;

end.
